using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;
using System.Security.Principal;
using System.Collections.Specialized;

namespace CodePlex.Resourceful
{
    public class HttpListenerContextAdapter : IHttpContext
    {
        private readonly HttpListenerContext _context;
        private readonly Uri _rootUri;

        private IHttpRequest _request;
        private IHttpResponse _response;


        public HttpListenerContextAdapter(HttpListenerContext context, Uri rootUri)
        {
            _context = context;
            _rootUri = rootUri;

            _request = new HttpListenerRequestAdapter(_context.Request, _rootUri);
            _response = new InternalResponse(_context);

            

        }

        public Uri RootUri
        {
            get { return _rootUri; }
        }


        public IHttpRequest Request
        {
            get { return _request; }
        }

        public IHttpResponse Response
        {
            get { return _response; }
        }



        public string BasicAuthUsername
        {
            get
            {

                return InternalUtils.GetBasicAuthUsername(this.Request.Headers);
            }
        }

        public string BasicAuthPassword
        {
            get
            {
                return InternalUtils.GetBasicAuthPassword(this.Request.Headers);
    
            }
        }



        private class HttpListenerRequestAdapter : IHttpRequest
        {

            private readonly HttpListenerRequest _request;
            private readonly Uri _rootUri;

            public HttpListenerRequestAdapter(HttpListenerRequest request, Uri rootUri)
            {
                _request = request;
                _rootUri = rootUri;
            }



            public bool IsRelative
            {
                get { return InternalUtils.IsRelative(_rootUri, _request.Url); }
            }

            public string RelativeUri
            {
                get { return InternalUtils.RelativeUri(_rootUri, _request.Url); }
            }

            public string HttpMethod
            {
                get { return _request.HttpMethod; }
            }

            public ReadOnlyList<string> AcceptTypes
            {
                get { return InternalUtils.GetAcceptTypes(_request.AcceptTypes); }
            }

            public string ContentType
            {
                get { return _request.ContentType; }
            }

            public Stream GetRequestStream()
            {
                return _request.InputStream;
            }




            public NameValuePairs Headers
            {
                get { return NameValuePairs.From(_request.Headers); }
            }

           
        }


        private class InternalResponse : IHttpResponse
        {


            private readonly HttpListenerContext _context;

            public InternalResponse(HttpListenerContext context)
            {
                _context = context;
            }
            public string ContentType
            {
                get
                {
                    return _context.Response.ContentType;
                }
                set
                {
                    _context.Response.ContentType = value;
                }
            }

            public int StatusCode
            {
                get
                {
                    return _context.Response.StatusCode;
                }
                set
                {
                    _context.Response.StatusCode = value;
                }
            }

            public string StatusDescription
            {
                get
                {
                    return _context.Response.StatusDescription;
                }
                set
                {
                    _context.Response.StatusDescription = value;
                }
            }

            public long ContentLength
            {
                set
                {
                    _context.Response.ContentLength64 = value;
                }
            }



            public Stream GetOutputStream()
            {
                return _context.Response.OutputStream;
            }

            public void End()
            {
                _context.Response.Close();
                _isEnded = true;
            }



            private bool _isEnded;
            public bool IsEnded
            {
                get { return _isEnded; }
            }



            public void SetHeader(string name, string value)
            {
                _context.Response.AddHeader(name, value);
            }
        }







    }

}
